//
// C++ Interface: callback
//
// Description: 
//
//
// Author: Os3 s.r.l. <xgui@os3.it>, (C) 2005
//
// Copyright: See COPYING file that comes with this distribution
//
//

namespace xgui
{
	//Callbacks Interfaces
	%feature("docstring","**DESCRIPTION**\n\nBasic interface for all callback types.\n\n**METHODS**\n\n") Callback;
	class Callback
	{
		protected:
			 Callback();

		public:
		    %feature("docstring","calls the method wrapped by this callback object. The method accepts the widget reference as the only parameter. It can return one of the follwing values: \n\n * *xgui::EVT_PROPAGATE:* the event is propagated to the next event handlers. \n\n * *xgui::EVT_BLOCK:* the event is not propagated. \n\n*C++*:: \n\n int call ( Widget * ); \n\n") call;
			 virtual int call(Widget *);
			 virtual ~Callback();
	};

    %feature("docstring","**DESCRIPTION**\n\ninterface for callback functions with a text parameter.\n\n**METHODS**\n\n") TextCallback;
	class TextCallback : public Callback
	{
		protected:
			 TextCallback();
	
		public:
		      %feature("docstring","calls the method wrapped by this callback object. The method accepts the widget reference and a text parameter.\n\n*C++*::\n\n int call(Widget *, std::string const &text);\n\n") call;
			 virtual int call(Widget *, std::string const &text);
			 virtual ~TextCallback();
	};

    %feature("docstring","**DESCRIPTION**\n\nInterface for callback functions with a text and an integer parameters.\n\n**METHODS**\n\n") TextStatusCallback;
	class TextStatusCallback : public Callback
	{
		protected:
			 TextStatusCallback();
	
		public:
		     %feature("docstring","calls the method wrapped by this callback object. The method accepts the widget reference, a text parameter and an integer parameter.\n\n*C++*::\n\n int call(Widget *, std::string const &text, int state);\n\n") call;
			 virtual int call(Widget *, std::string const &text, int state);
			 virtual ~TextStatusCallback();

	};

    %feature("docstring","**DESCRIPTION**\n\ninterface for callback functions with two string parameter.\n\n**METHODS**\n\n") TextPairCallback;
	class TextPairCallback : public Callback
	{
		protected:
			 TextPairCallback();
	
		public:
		     %feature("docstring","calls the method wrapped by this callback object. The method accepts the widget reference and two string parameters.\n\n*C++*::\n\n int call(Widget *, std::string const &text1, std::string const &text2);\n\n") call;
			 virtual int call(Widget *, std::string const &text1, std::string const &text2);
			 virtual ~TextPairCallback();

	};

    %feature("docstring","**DESCRIPTION**\n\nPython wrapper for :class:`xgui.Callback` callback.\n\n**CONSTRUCTOR**\n\n") PyCallback;
	class PyCallback : public xgui::Callback
	{
		public:
		    %feature("docstring","initializes the PyCallback class with the specified function pointer\n\n") PyTextCallback;
			PyCallback(PyObject * cb);
			virtual ~PyCallback();
			virtual int call(xgui::Widget *w);
	};

    %feature("docstring","**DESCRIPTION**\n\nPython wrapper for :class:`xgui.TextCallback` callback.\n\n**CONSTRUCTOR**\n\n") PyTextCallback;	
	class PyTextCallback : public xgui::TextCallback
	{
		public:
		    %feature("docstring","initializes the PyTextCallback class with the specified function pointer\n\n") PyTextCallback;
			PyTextCallback(PyObject * cb);
			virtual ~PyTextCallback();
			virtual int call(xgui::Widget *w, std::string const &str);
	};

    %feature("docstring","**DESCRIPTION**\n\nPython wrapper for :class:`xgui.TextStatusCallback` callback.\n\n**CONSTRUCTOR**\n\n") PyTextStatusCallback;	
	class PyTextStatusCallback : public xgui::TextStatusCallback
	{
		public:
		    %feature("docstring","initializes the PyTextStatusCallback class with the specified function pointer\n\n") PyTextStatusCallback;
			PyTextStatusCallback(PyObject * cb);
			virtual ~PyTextStatusCallback();
			virtual int call(xgui::Widget *w, std::string const &str, int status);
	};

    %feature("docstring","**DESCRIPTION**\n\nPython wrapper for :class:`xgui.TextPairCallback` callback.\n\n**CONSTRUCTOR**\n\n") PyTextStatusCallback;	
	class PyTextPairCallback : public xgui::TextPairCallback
	{
		public:
		   %feature("docstring","initializes the PyTextPairCallback class with the specified function pointer\n\n") PyTextPairCallback;
			PyTextPairCallback(PyObject * cb);
			virtual ~PyTextPairCallback();
			virtual int call(xgui::Widget *w, std::string const &str, std::string const &str2);
	};
}


%{
namespace xgui 
{
	class PyCallback : public xgui::Callback
	{
		private:
			PyObject * callback;
	
		public:
			PyCallback(PyObject * cb) 
			: xgui::Callback(), callback(cb) 
			{ 
				if (!PyCallable_Check(cb)) {
					PyErr_SetString(PyExc_TypeError, "Non callable object to PyCallback");
					PyErr_Print();
				}
	
				Py_INCREF(cb); 
			}
			
			virtual ~PyCallback() 
			{ 
				Py_DECREF(callback); 
			}
	
			virtual int call(xgui::Widget *w) 
			{
				int rv = 0;
				
				bool should_allow = PythonThreadsManager::DenyThreads();
	
				if (PyCallable_Check(callback)) {
					PyObject *pw =  XGUIPyObjectCreate(w, false);
					PyObject *args = Py_BuildValue("(O)", pw);
					PyObject *result = PyEval_CallObject(callback, args);
					Py_XDECREF(args);
					Py_XDECREF(pw);
	
					if (result == 0) {
						PyErr_Print();
					}
					else if (result == Py_None) {
						Py_XDECREF(result);
					}
					else if (PyInt_Check(result)) {
						rv = PyInt_AsLong(result);
						Py_XDECREF(result);
					}
					else {
						Py_XDECREF(result);
						PyErr_SetString(PyExc_TypeError, "Expected Integer or None as return value of callback");
						PyErr_Print();
					}
				}
				else {
					PyErr_SetString(PyExc_TypeError, "Non callable object to PyCallback");
					PyErr_Print();
				}
	
				if ( should_allow ) PythonThreadsManager::AllowThreads();
				
				return rv;
			}
	};
	
	class PyTextCallback : public xgui::TextCallback
	{
		private:
			PyObject * callback;
	
		public:
			PyTextCallback(PyObject * cb) 
			: xgui::TextCallback(), callback(cb) 
			{ 
				if (!PyCallable_Check(cb)) {
					PyErr_SetString(PyExc_TypeError, "Non callable object to PyCallback");
					PyErr_Print();
				}
	
				Py_INCREF(cb); 
			}
			
			virtual ~PyTextCallback() 
			{ 
				Py_DECREF(callback); 
			}
	
	
			virtual int call(xgui::Widget *w, std::string const &text) 
			{
				int rv = 0;
	
				bool should_allow = PythonThreadsManager::DenyThreads();
				
				if (PyCallable_Check(callback)) {
					PyObject *pw =  XGUIPyObjectCreate(w, false);
					PyObject *args = Py_BuildValue("(Os)", pw, text.c_str());
					PyObject *result = PyEval_CallObject(callback, args);
					Py_XDECREF(args);
					Py_XDECREF(pw);
					
					if (result == 0) {
						PyErr_Print();
					}
					else if (result == Py_None) {
						Py_XDECREF(result);
					}
					else if (PyInt_Check(result)) {
						rv = PyInt_AsLong(result);
						Py_XDECREF(result);
					}
					else {
						Py_XDECREF(result);
						PyErr_SetString(PyExc_TypeError, "Expected Integer or None as return value of callback");
						PyErr_Print();
					}
				}
				else {
					PyErr_SetString(PyExc_TypeError, "Non callable object to PyCallback");
					PyErr_Print();
				}
	
				if ( should_allow ) PythonThreadsManager::AllowThreads();
				
				return rv;
			}
	};
	
	class PyTextStatusCallback : public xgui::TextStatusCallback
	{
		private:
			PyObject * callback;
	
		public:
			PyTextStatusCallback(PyObject * cb) 
			: xgui::TextStatusCallback(), callback(cb) 
			{ 
				if (!PyCallable_Check(cb)) {
					PyErr_SetString(PyExc_TypeError, "Non callable object to PyCallback");
					PyErr_Print();
				}
	
				Py_INCREF(cb); 
			}
			
			virtual ~PyTextStatusCallback() 
			{ 
				Py_DECREF(callback); 
			}
	
	
			virtual int call(xgui::Widget *w, std::string const &text, int status) 
			{
				int rv = 0;
	
				bool should_allow = PythonThreadsManager::DenyThreads();
				
				if (PyCallable_Check(callback)) {
					PyObject *pw =  XGUIPyObjectCreate(w, false);
					PyObject *args = Py_BuildValue("(Osi)", pw, text.c_str(), status);
					PyObject *result = PyEval_CallObject(callback, args);
					Py_XDECREF(args);
					Py_XDECREF(pw);
					
					if (result == 0) {
						PyErr_Print();
					}
					else if (result == Py_None) {
						Py_XDECREF(result);
					}
					else if (PyInt_Check(result)) {
						rv = PyInt_AsLong(result);
						Py_XDECREF(result);
					}
					else {
						Py_XDECREF(result);
						PyErr_SetString(PyExc_TypeError, "Expected Integer or None as return value of callback");
						PyErr_Print();
					}
				}
				else {
					PyErr_SetString(PyExc_TypeError, "Non callable object to PyCallback");
					PyErr_Print();
				}
	
				if ( should_allow ) PythonThreadsManager::AllowThreads();
	
				return rv;
			}
	};
	
	class PyTextPairCallback : public xgui::TextPairCallback
	{
		private:
			PyObject * callback;
	
		public:
			PyTextPairCallback(PyObject * cb) 
			: xgui::TextPairCallback(), callback(cb) 
			{ 
				if (!PyCallable_Check(cb)) {
					PyErr_SetString(PyExc_TypeError, "Non callable object to PyCallback");
					PyErr_Print();
				}
	
				Py_INCREF(cb); 
			}
			
			virtual ~PyTextPairCallback() 
			{ 
				Py_DECREF(callback); 
			}
	
	
			virtual int call(xgui::Widget *w, std::string const &text, std::string const &text2) 
			{
				int rv = 0;
	
				bool should_allow = PythonThreadsManager::DenyThreads();
				
				if (PyCallable_Check(callback)) {
					PyObject *pw =  XGUIPyObjectCreate(w, false);
					PyObject *args = Py_BuildValue("(Oss)", pw, text.c_str(), text2.c_str());
					PyObject *result = PyEval_CallObject(callback, args);
					Py_XDECREF(args);
					Py_XDECREF(pw);
					
					if (result == 0) {
						PyErr_Print();
					}
					else if (result == Py_None) {
						Py_XDECREF(result);
					}
					else if (PyInt_Check(result)) {
						rv = PyInt_AsLong(result);
						Py_XDECREF(result);
					}
					else {
						Py_XDECREF(result);
						PyErr_SetString(PyExc_TypeError, "Expected Integer or None as return value of callback");
						PyErr_Print();
					}
				}
				else {
					PyErr_SetString(PyExc_TypeError, "Non callable object to PyCallback");
					PyErr_Print();
				}
	
				if ( should_allow ) PythonThreadsManager::AllowThreads();
	
				return rv;
			}
	};
}
%}


